-- Some Dope on Zope --
--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==
Zope и безопасность
=-=-=-=-=-=-=-=-=-=
Особо распинаться про то, что такое Zope, я не планирую. Если вы еще не знакомы
с этой системой, то всю необходимую информацию можно найти на официальном
web-сайте [1]. В двух словах, Zope - это полностью объектно-ориентированный
сервер приложений web, почти полностью написанный на языке Python [2], после
осознания всех возможностей которого все старания php-кодеров над собственными
CMS вызывают лишь улыбку и сочувствие. Данная статья посвящена обзору основных
встроенных средств безопасности Zope.
Zope - очень защищенная система. Если посмотреть архивы багтрака на предмет
вопросов безопасности, связанных с этой системой, то максимум чего смогли
добиться сексперты, так это инициировать трейсбек, содержащий физический путь,
по которому установлен Zope в системе при помощи всяких там кривых XML-RPC [
хотя на самом деле есть куда более простые как локальные так и удаленные методы
получения аналогичного результата, только какой от них смысл - в контексте Zope
это не дает ровным счетом ничего ].
С самого начала Zope разрабатывалась как система многопользовательская, поэтому
там реализовано такое понятие как Роли [ Roles ], которые есть ни что иное как
ACL [ Access Control Lists ]. Благодаря ролям, назначаемым пользователям, в Zope
гораздо проще организовать грамотный и безопасный workflow, в отличие от тех же
PHP CMS, где каждый автор реализует это понятие с учетом собственных
представлений что, как показала практика, не всегда есть лучший вариант.
По умолчанию Zope имеет четыре роли - Manager, Owner [ различие лишь в уровне
доступа к объектам и методам ], Anonymous [ эту роль имеет любой пользователь,
не авторизовавшийся в системе ] и Authenticated [ неявная роль, которой
наделяется любой пользователь, авторизованный в системе ]. Помимо этого также
существует возможность создания Emergency User - пользователя, который не может
ничего, кроме как создавать других пользователей [ на случай, если вы
забудете/лишитесь )) пароля к своему основному пользователю с ролью Manager или
еще что ], создать которого нельзя через интерфейс ZMI, только с консоли,
посредством выполнения сценария zpasswd.py. Естесственно, вы имеете возможность
создания новых ролей и изменения уже существующих. Также каждый пользователь
может иметь более одной роли. Говоря другими словами, каждый пользователь может
входить в несколько групп пользователей, каждая группа которых наделена тем или
иным набором полномочий.
Zope авторизует пользователя через тип авторизации, именуемой ``Zope'' [
аналогична Basic Auth в Apache ], хотя помимо этого существует еще несколько
встроенных возможностей контроля доступа. В частности, для каждого пользователя
можно указать конкретный IP или имя хоста [ равно как диапазон IP или имя хоста
вида *.dialup.nigger.co.za ], с которых возможен доступ для этого пользователя.
То есть, если я работаю в Zope только с локальной машины, то я могу прописать IP
127.0.0.1 и тогда любой, даже знающий пароль этого пользователя, но имеющий
отличный от этого IP, не сможет получить доступа к интерфейсу управления Zope.
Для организации поддержания сессии пользователя посредством cookie, можно
установить продукт CookieCrumbler и добавить его экземпляр в папку, для доступа
к которой необходимо авторизоваться. Об этом мы поговорим позже и рассмотрим на
примере в конце статьи. Сейчас же я хочу рассказать о создании новых ролей и
разновидностях полномочий.
Для создания новой роли нужно перейти в Root Folder и выбрать вкладку Security.
На этой вкладке перечислены все существующие роли и списки их полномочий. Вот
здесь вы и можете вносить коррективы в существующие роли, то есть добавлять или
удалять полномочия. Однако обращу ваше внимание, что в Zope используется
механизм наследования, поэтому все изменения в доступе к Root Folder отразятся
на всех вложенных в нее объектах. К примеру, если вы лишите роли Anonymous
полномочия на доступ к объектам, то при заходе на http://your_site.ru
пользователя сперва попросят авторизоваться. То же самое относится и к
гипотетическому объекту-папке, расположенному уровнем ниже -
http://your_site.ru/test_folder/. Если же вы хотите ограничить доступ только к
этой папке, то вам нужно перейти в нее через ZMI, выбрать вкладку Security и
убрать галочку напротив опции Access Transient Objects у роли Anonymous.
Так или иначе, на вкладке Security, в самом низу страницы есть небольшая форма
``User defined roles''. Введите в этом поле имя желаемой роли и нажмите кнопку
Add role. Теперь рассмотрим сами доступные полномочия [ естесственно, по мере
добавления в систему новых продуктов, их состав будет изменяться ]. Вот список
основных, наиболее часто используемых, хотя на самом деле их гораздо больше.
Более подробное описание каждого из объектов, в том числе здесь не
перечисленных, смотрите в Zope Book [3].
Access Transient Objects
------------------------
Способность просматривать содержимое нерезидентных объектов.
Access contents information
---------------------------
Способность просматривать содержимое объекта. Это одно из ключевых полномочий.
Access session data
-------------------
Способность просматривать информацию о сессии пользователя.
Add Documents, Images, and Files
--------------------------------
Способность добавлять Документы, Изображения и Файлы.
Add External Methods
--------------------
Способность добавлять Внешние Методы. То есть средствами Zope вызывать внешние
программы, не являющиеся объектами Zope и расположенными где-то в файловой
системе, куда Zope имеет доступ.
Add Folders
-----------
Способность добавлять Папки - контейнеры объектов.
Add MailHost objects
--------------------
Способность добавлять объекты MailHost. Эти объекты используются для указания
почтового релея, через который будут отправляться любые сообщения электронной
почты. Это удобно при использовании в различных сценариях получения обратной
связи от пользователей, etc.
Add Page Templates
------------------
Способность добавлять Шаблоны Документов. В Zope имеется встроенный макроязык
шаблонов страниц [ ZPT ].
Add Python Scripts
------------------
Способность добавлять Сценарии Python. Это не то же самое что и python CGI, так
что не путайте.
Add User Folders
----------------
Способность добавлять Специальный объект User Folder, служащий для создания
механизма авторизации и управления пользователями. О нем будет сказано более
подробно ниже. Получить имя пользователя, с которым тот вошел в систему можно
при помощи вызова функции SecurityGetUser().getUserName(). То есть, в
DTML-страницу/метод засовываем такой код:
Ваше имя: <dtml-var expr="_.SecurityGetUser().getUserName()">
Add Virtual Host Monsters
-------------------------
Способность добавлять VHM. Virtual Host Monster - это объект, позволяющий
создавать виртуальные хосты без помощи Apache.
Add ZCatalogs
-------------
Способность добавлять объекты индексирования web-контента ZCatalog.
Add Zope Tutorials
------------------
Способность добавлять экземпляры Zope Tutorial - руководства по использованию
Zope с примерами программ.
Change DTML Documents
---------------------
Способность изменять Документы DTML
Change DTML Methods
-------------------
Способность изменять Методы DTML.
Change External Methods
-----------------------
Способность изменять Внешние Методы.
Change Images and Files
-----------------------
Способность изменять Изображения и Файлы.
Change Page Templates
---------------------
Способность изменять Шаблоны Страниц.
Change Python Scripts
---------------------
Способность изменять Сценарии Python.
Change configuration
--------------------
Способность изменять конфигурацию.
Change permissions
------------------
Способность изменять права доступа.
Copy or Move
------------
Способность копировать или перемещать объекты.
Create Transient Objects
------------------------
Способность создавать нерезидентные объекты.
Create class instances
----------------------
Способность создавать экземпляры класса.
Define permissions
------------------
Способность определять права доступа.
Delete objects
--------------
Способность удалять объекты
FTP access
----------
Способность работы с Zope по протоколу FTP [ порт 8021 по умолчанию ].
Import/Export objects
---------------------
Способность импортировать и экспортировать объекты.
Log Site Errors
---------------
Способность регистрировать возникающие ошибки
Log to the Event Log
--------------------
Способность вести регистрацию событий
Manage Access Rules
-------------------
Способность управлять правилами доступа
Manage Z Classes
----------------
Способность управлять Z классами
Manage ZCatalog Entries
-----------------------
Способность управлять данными системы индексирования ZCatalog
Manage properties
-----------------
Способность изменять свойства объектов.
Manage users
------------
Способность управлять пользователями.
Open/Close Database Connection
------------------------------
Способность открывать/закрывать соединение с базой данных.
Search ZCatalog
---------------
Способность осуществлять поиск при помощи ZCatalog.
Take ownership
--------------
Способность становиться владельцем объекта.
Undo changes
------------
Способность отменять внесенные в объект изменения.
View
----
Способность просматривать объект.
View History
------------
Способность просматривать историю изменений объекта.
View management screens
-----------------------
Способность просматривать экраны управления объектами.
WebDAV access
-------------
Способность доступа по протоколу WebDAV
Окей, с этим разобрались. Теперь рассмотрим практическую задачу. К примеру, нам
нужно создать архив приватной информации, доступ к которой будет осуществляться
по логину и паролю. В корне создадим объект-папку super_private. Теперь перейдем
в нее, откроем вкладку Security и добавим новую роль, скажем, ``membah''. В эту
же папку добавим объект User Folder, в нем создадим пользователя chuvak и дадим
ему роль membah. Снова открываем вкладку Security в папке super_private. Там
нужно убрать все флажки, соответствующие роли Anonymous. То же самое можно
проделать и с другими ролями, главное не забыть оставить себе доступ для
добавления и изменения объектов, добавления пользователей, etc. Как вы можете
видеть, помимо четырех основном ролей, на вкладке Security теперь появилась роль
membah - вот для нее и нужно установить соответствующие права. Предположим, что
все, кому мы дадим акаунт с ролью membah, будут только читать размещенную нами
информацию, но не будут иметь возможности ее добавления или изменения. Для этого
убираем у роли membah все кроме полномочий Access contents information и View.
По желанию также в папке User Folder определяем домен или IP, с которого будет
ходить наш пользователь chuvak.
Вот так. Теперь при попытке зайти по адресу http://your_site.ru/super_private/ у
пользователя будут спрашивать логин и пароль.
Окей, теперь неплохо бы добавить поддержание сессии при помощи cookie. Для этого
установим продукт CookieCrumbler [4] и поместим его экземпляр в папку
super_private [ при помощи ZMI ]. Теперь все готово к употреблению. Вы можете
использовать поставляющиеся с CookieCrumbler DTML-методы login_form, logged_in и
logged_out, а можете использовать свои.
В конечном итоге у вас должна получиться примерно следующая минимальная иерархия
объектов:
[Root Folder]
[super_pivate]
[User folder]
[chuvak]
[CookieCrumbler]
[logged_in]
[logged_out]
[login_form]
[index_html]
Окей. Это что касается встроенных средств. Но на самом деле ваши возможности
ограничиваются только вашим воображением. Предположим, что хакИр
угадал/узнал/подобрал пароль к пользователю chuvak, который, напомню, является
мембером вашей приватной тусовки, а поскольку чел сей меняет провайдеров как
перчатки, вы не прописывали в свойствах его IP/dns. Предотвратить такое
можно, к примеру, таким вот образом - мы придумаем какую-нить длинную и
непонятную passphrase, ну, скажем, ``l33t0^b0r1t0#%@(()!+_dd'' и будем
показывать контент приват-зоны только тем, кто:
1. аутентифицирован
2. является членом группы(роли) membah
3. в поле HTTP_USER_AGENT имеет ту самую l33t0^b0r1t0#%@(()!+_dd
Если, допустим, пользователь зашел с правильным паролем, но в HTTP_USER_AGENT у
него какой-нибудь там ``Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)'', то
мы прописываем ему болт и демонстрируем чудеса JavaScript ). Как мы это
сделаем?? Легко. В каждую DTML страницу прописываем примерно следующее:
<dtml-if expr="REQUEST.get('HTTP_USER_AGENT') == 'l33t0^b0r1t0#%@(()!+_dd'">
"""
здесь идет защищенный контент страницы
"""
<dtml-else>
<h1>.:"fuck 0ff n1gg4":.</h1>
"""
а здесь идет какой-нибудь злой код ). напишите
сами или скопируйте из статьи о багах в IE
"""
</dtml-else>
</dtml-if>
И так для каждой ``защищенной страницы''. Это тупой способ, но рабочий. Конечно,
все можно сделать гораздо красивей и приятней, к примеру, сохранить этот код в
отдельный DTML метод и вызывать его в каждом документе по необходимости [ а
проще добавить его вызов в standard_html_header - если вы не удаляете его
включение из каждого создаваемого объекта ] и все дела. Тогда для смены вашей
passphrase вам понадобится изменить только этот метод и больше ничего.
Чтобы не усложнять себе жизнь, я оставляю реализацию этого способа в качестве
вашего домашнего задания. Плагины для изменения HTTP_USER_AGENT для браузера
Mozilla Firebird можно взять на странице с плагинами Mozilla'ы - там их как
минимум два, а то и больше, да и для IE, я думаю, есть что-то подобное.
На этом все. Если эта тема будет кому-либо интересна, то, возможно, статья будет
иметь продолжение в последующих выпусках D.
Ссылки
------
[1] Официальный web-сайт Zope - www.zope.org
[2] Официальный сайт Python - www.python.org
[3] Zope Book - http://zope.org/Documentation/Books/ZopeBook/2_6Edition/
[4] CookieCrumbler - http://hathaway.freezope.org/Software/CookieCrumbler